home *** CD-ROM | disk | FTP | other *** search
/ PC Elektro 3 / PC-Elektro-3-cd1.bin / KBan 2.0 / KBANSRC.LZH / SRC / PROG / KBANVIEW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-10-07  |  30.7 KB  |  972 lines

  1. // the implementation of CKBANView
  2. // Copyright (C) 1997 Kazutaka Hirata <khirata@jove.acs.unt.edu>
  3.  
  4. #include "stdafx.h"
  5.  
  6. #include <string.h>
  7. #include "cmd/edpndlg.h"
  8. #include "view/aptpin.h"
  9. #include "view/aptline.h"
  10. #include "view/setgrid.h"
  11. #include "draw.h"
  12. #include "memdc.h"
  13. #include "resource.h"
  14.  
  15. #include "kbanview.h"
  16.  
  17. IMPLEMENT_DYNCREATE(CKBANView, CScrollView)
  18.  
  19. BEGIN_MESSAGE_MAP(CKBANView, CScrollView)
  20.   ON_WM_ERASEBKGND()
  21.   ON_WM_KEYDOWN()
  22.   ON_WM_KEYUP()
  23.   ON_WM_CHAR()
  24.   ON_WM_MOUSEMOVE()
  25.   ON_WM_LBUTTONUP()
  26.   ON_WM_LBUTTONDOWN()
  27.   ON_WM_RBUTTONUP()
  28.   ON_WM_RBUTTONDOWN()
  29.   ON_WM_SIZE()
  30.   ON_WM_MOVE()
  31.   ON_WM_VSCROLL()
  32.   ON_WM_HSCROLL()
  33.  
  34.   // edit
  35.   ON_COMMAND          (ID_EDIT_UNDO                             , OnUndo               )
  36.   ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO                             , OnUpdateUndo         )
  37.   ON_COMMAND          (ID_EDIT_REDO                             , OnRedo               )
  38.   ON_UPDATE_COMMAND_UI(ID_EDIT_REDO                             , OnUpdateRedo         )
  39.   ON_COMMAND_RANGE    (ID_EDIT_BLOCK       , ID_EDIT_BLOCK      , OnChangeCommand      )
  40.   ON_COMMAND_RANGE    (ID_EDIT_BLOCK_LAYER , ID_EDIT_BLOCK_LAYER, OnChangeCommand      )
  41.   ON_COMMAND_RANGE    (ID_EDIT_CUT         , ID_EDIT_CUT        , OnEditCutCopyDelete  )
  42.   ON_UPDATE_COMMAND_UI(ID_EDIT_CUT                              , OnUpdateCutCopyDelete)
  43.   ON_COMMAND_RANGE    (ID_EDIT_COPY        , ID_EDIT_COPY       , OnEditCutCopyDelete  )
  44.   ON_UPDATE_COMMAND_UI(ID_EDIT_COPY                             , OnUpdateCutCopyDelete)
  45.   ON_COMMAND_RANGE    (ID_EDIT_DELETE      , ID_EDIT_DELETE     , OnEditCutCopyDelete  )
  46.   ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE                           , OnUpdateCutCopyDelete)
  47.   ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE                            , OnUpdatePaste        )
  48.   ON_COMMAND_RANGE    (ID_EDIT_PASTE       , ID_EDIT_PASTE      , OnChangeCommand      )
  49.   ON_COMMAND          (ID_EDIT_UNSELECT_ALL                     , OnEditUnselectAll    )
  50.   ON_UPDATE_COMMAND_UI(ID_EDIT_UNSELECT_ALL                     , OnUpdateUnselectAll  )
  51.   ON_COMMAND_RANGE    (ID_EDIT_PIN         , ID_EDIT_MOVE_LINE  , OnChangeCommand      )
  52.  
  53.   // layer
  54.   ON_COMMAND_RANGE          (ID_LAYER_PCOMMON     , ID_LAYER_SBOTTOM     , OnChangeLayer    )
  55.   ON_UPDATE_COMMAND_UI_RANGE(ID_LAYER_PCOMMON     , ID_LAYER_SBOTTOM     , OnUpdateLayer    )
  56.   ON_COMMAND_RANGE          (ID_LAYER_SHOW_PCOMMON, ID_LAYER_SHOW_SBOTTOM, OnChangeShowLayer)
  57.   ON_UPDATE_COMMAND_UI_RANGE(ID_LAYER_SHOW_PCOMMON, ID_LAYER_SHOW_SBOTTOM, OnUpdateShowLayer)
  58.  
  59.   // view
  60.   ON_COMMAND_RANGE(ID_VIEW_ZOOMIN, ID_VIEW_ZOOMOUT, OnZoomCore)
  61.   ON_COMMAND_RANGE(ID_VIEW_ALL   , ID_VIEW_ALL    , OnZoomCore)
  62.   ON_COMMAND      (ID_VIEW_REDRAW                 , OnRedraw  )
  63.  
  64.   // setup
  65.   ON_COMMAND                (ID_SETUP_SNAP         , OnChangeSnap       )
  66.   ON_UPDATE_COMMAND_UI      (ID_SETUP_SNAP         , OnUpdateSnap       )
  67.   ON_COMMAND                (ID_SETUP_PIN_ON_COMMON, OnChangePinOnCommon)
  68.   ON_UPDATE_COMMAND_UI      (ID_SETUP_PIN_ON_COMMON, OnUpdatePinOnCommon)
  69.   ON_COMMAND                (ID_SETUP_FILL         , OnChangeFill       )
  70.   ON_UPDATE_COMMAND_UI      (ID_SETUP_FILL         , OnUpdateFill       )
  71.   ON_COMMAND                (ID_SETUP_HOLE         , OnChangeHole       )
  72.   ON_UPDATE_COMMAND_UI      (ID_SETUP_HOLE         , OnUpdateHole       )
  73.   ON_COMMAND                (ID_HELP_DEBUG         , OnHelpDebug        )
  74.   ON_COMMAND_RANGE          (ID_SETUP_GRID_10_1    , ID_SETUP_GRID_25_A, OnChangeGrid)
  75.   ON_UPDATE_COMMAND_UI_RANGE(ID_SETUP_GRID_10_1    , ID_SETUP_GRID_25_A, OnUpdateGrid)
  76.   ON_COMMAND                (ID_SETUP_GRID_RESET   , OnResetGrid        )
  77.   ON_COMMAND_RANGE          (ID_SETUP_GRID_ORIGIN  , ID_SETUP_GRID_ORIGIN, OnChangeCommand)
  78.   ON_COMMAND                (ID_SETUP_GRID_WIDTH   , OnSetGridWidth     )
  79.   ON_COMMAND                (ID_SETUP_APT_PIN      , OnAptPin           )
  80.   ON_COMMAND                (ID_SETUP_APT_LINE     , OnAptLine          )
  81.  
  82.   // tools & help
  83.   ON_COMMAND(ID_TOOLS_PURGE , OnToolsPurge)
  84.   ON_COMMAND(ID_HELP_ISEMPTY, OnIsEmpty   )
  85.  
  86.   // place & delete
  87.   ON_COMMAND_RANGE(ID_PLACE_PIN , ID_PLACE_COMPONENT , OnChangeCommand)
  88.   ON_COMMAND_RANGE(ID_DELETE_PIN, ID_DELETE_COMPONENT, OnChangeCommand)
  89.  
  90.   // context menu
  91.   ON_COMMAND(ID_CTXT_EDIT_PIN          , OnContextEditPin          )
  92.   ON_COMMAND(ID_CTXT_SELECT_PIN        , OnContextSelectPin        )
  93.   ON_COMMAND(ID_CTXT_UNSELECT_PIN      , OnContextUnselectPin      )
  94.   ON_COMMAND(ID_CTXT_SELECT_LINE       , OnContextSelectLine       )
  95.   ON_COMMAND(ID_CTXT_UNSELECT_LINE     , OnContextUnselectLine     )
  96.   ON_COMMAND(ID_CTXT_SELECT_COMPONENT  , OnContextSelectComponent  )
  97.   ON_COMMAND(ID_CTXT_UNSELECT_COMPONENT, OnContextUnselectComponent)
  98.  
  99.   // status bar
  100.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_X      , OnUpdateIndicatorX      )
  101.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_Y      , OnUpdateIndicatorY      )
  102.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_LAYER  , OnUpdateIndicatorLayer  )
  103.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_ZOOM   , OnUpdateIndicatorZoom   )
  104.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_GRID   , OnUpdateIndicatorGrid   )
  105.   ON_UPDATE_COMMAND_UI(ID_INDICATOR_COMMAND, OnUpdateIndicatorCommand)
  106. END_MESSAGE_MAP()
  107.  
  108. CKBANView::CKBANView()
  109.   : CScrollView(),
  110.     m_moved(FALSE),
  111.     m_nGridID(ID_SETUP_GRID_25_1),
  112.     m_nLayerID(ID_LAYER_PTOP)
  113. {
  114.   m_bDisableRedraw = false;
  115. }
  116.  
  117. void CKBANView::OnInitialUpdate()
  118. {
  119.   KBAN_INFO& info = GetDocument()->kban_info();
  120.   info.active_layer().pin_on_common().set(true);
  121.  
  122.   for(uint i = 0; i < LAYER_NUMBER; i++) {
  123.     info.lflags()[i] = true;
  124.   }
  125.   info.grid().zoom_set(50);
  126.   const XY& pc_design_size = info.grid().get_pc_design_size();
  127.   SetScrollSizes(MM_TEXT, CSize(pc_design_size.x(), pc_design_size.y()));
  128.   ScrollToPosition(CPoint(0, pc_design_size.y()));
  129.  
  130.   if(!info.apt_pin_table().is_included(info.apt_pin())) {
  131.     info.apt_pin_table().push_back(info.apt_pin());
  132.   }
  133.   if(!info.apt_line_table().is_included(info.apt_line())) {
  134.     info.apt_line_table().push_back(info.apt_line());
  135.   }
  136.  
  137.   CClientDC dc(this);
  138.   m_current_mmi = &m_default_func;
  139.   KBAN_DRAW draw(&dc, info.grid(), info.fill(), info.hole(), info.lflags());
  140.   m_current_mmi->init(info, draw);
  141.  
  142.   OnZoomCore(ID_VIEW_ALL);
  143.  
  144.   GetDocument()->SetNewState("");
  145.   GetDocument()->ClearHistory();
  146.  
  147.   CScrollView::OnInitialUpdate();
  148. }
  149.  
  150. BOOL CKBANView::OnEraseBkgnd(CDC* pDC)
  151. {
  152.   if(m_bDisableRedraw) {
  153.     return TRUE;
  154.   }
  155.  
  156.   CRect rect;
  157.   pDC->GetClipBox(&rect);
  158.   pDC->FillSolidRect(&rect, RGB(0, 0, 0));
  159.  
  160.   return TRUE;
  161. }
  162.  
  163. void CKBANView::OnDraw(CDC* pDC)
  164. {
  165.   if(m_bDisableRedraw) {
  166.     return;
  167.   }
  168.  
  169.   KBAN_INFO& info = GetDocument()->kban_info();
  170. #if 1
  171.   KBAN_DRAW draw(pDC, info.grid(), info.fill(), info.hole(), info.lflags());
  172. #else
  173.   const XY& pc_win_size = info.grid().get_pc_win_size();
  174.   CMemoryDC memDC(pDC, pc_win_size.x(), pc_win_size.y(), 16);
  175.   memDC.SetViewportOrg(pDC->GetViewportOrg());
  176.   CRect rcClip;
  177.   memDC.GetClipBox(&rcClip);
  178.   memDC.FillSolidRect(&rcClip, RGB(0, 0, 0));
  179.   KBAN_DRAW draw(&memDC, info.grid(), info.fill(), info.hole());
  180. #endif
  181.   draw.draw_grid();
  182.   KBAN_DATA& kban_data = info.kban_data();
  183.   uint active_layer = info.active_layer().get();
  184.   draw.draw_kban_data(kban_data, active_layer);
  185.  
  186.   if(info.bSelected()) {
  187.     KBAN_DATA& kban_data = info.kban_data();
  188.     KBAN_DATA kban_data_selected;
  189.     kban_data.collect_selected_items(kban_data_selected);
  190.     draw.draw_kban_data_target(kban_data_selected, active_layer);
  191.   }
  192.  
  193.   m_current_mmi->redraw(info, draw);
  194. #if 1
  195. #else
  196.   pDC->BitBlt(
  197.     rcClip.left,
  198.     rcClip.top ,
  199.     rcClip.right  - rcClip.left,
  200.     rcClip.bottom - rcClip.top ,
  201.     &memDC,
  202.     rcClip.left,
  203.     rcClip.top ,
  204.     SRCCOPY
  205.   );
  206. #endif
  207.   if(m_moved) {
  208.     CPoint point(m_dc_old.x(), m_dc_old.y());
  209.     pDC->DPtoLP(&point);
  210.     XY pc_old(point.x, point.y);
  211.     m_current_mmi->mouse_move(info, draw, pc_old, 0);
  212.   }
  213. }
  214.  
  215. #define PREPARE()                                             \
  216.   CClientDC dc(this);                                         \
  217.   OnPrepareDC(&dc);                                           \
  218.   KBAN_INFO& info = GetDocument()->kban_info();               \
  219.   KBAN_DRAW draw(&dc, info.grid(), info.fill(), info.hole(), info.lflags());
  220.  
  221. void CKBANView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  222. {
  223.   PREPARE();
  224.   switch(nChar) {
  225.     case VK_UP    : OnChar(nChar, nRepCnt, nFlags); break;
  226.     case VK_DOWN  : OnChar(nChar, nRepCnt, nFlags); break;
  227.     case VK_LEFT  : OnChar(nChar, nRepCnt, nFlags); break;
  228.     case VK_RIGHT : OnChar(nChar, nRepCnt, nFlags); break;
  229.     case VK_SHIFT : {
  230.       if((nFlags & 0x4000) == 0) { // not pressed previously
  231.         m_current_mmi->shift_down(info, draw);
  232.       }
  233.       break;
  234.     }
  235.     case VK_CONTROL  : {
  236.       if((nFlags & 0x4000) == 0) { // not pressed previously
  237.         m_current_mmi->control_down(info, draw);
  238.       }
  239.       break;
  240.     }
  241.   }
  242. }
  243.  
  244. void CKBANView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
  245. {
  246.   PREPARE();
  247.   switch(nChar) {
  248.     case VK_SHIFT : {
  249.       if((nFlags & 0x8000) != 0) { // being released
  250.         m_current_mmi->shift_up(info, draw);
  251.       }
  252.       break;
  253.     }
  254.     case VK_CONTROL  : {
  255.       if((nFlags & 0x8000) != 0) { // being released
  256.         m_current_mmi->control_up(info, draw);
  257.       }
  258.       break;
  259.     }
  260.   }
  261. }
  262.  
  263. void CKBANView::OnScrollCore(SCROLL_DIRECTION sd)
  264. {
  265.    CPoint point = GetScrollPosition();
  266.    KBAN_INFO& info = GetDocument()->kban_info();
  267.    const XY& pc_win_size = info.grid().get_pc_win_size();
  268.    switch(sd) {
  269.      case SCROLL_UP    : point.y -= pc_win_size.y() / 4; break;
  270.      case SCROLL_DOWN  : point.y += pc_win_size.y() / 4; break;
  271.      case SCROLL_LEFT  : point.x -= pc_win_size.x() / 4; break;
  272.      case SCROLL_RIGHT : point.x += pc_win_size.x() / 4; break;
  273.    }
  274.    ScrollToPosition(point);
  275.    Invalidate();
  276. }
  277.  
  278. void CKBANView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  279. {
  280.   for(int i = 0; i < HIDDEN_STRING_LEN - 1; i++) {
  281.     m_hidden_string[i] = m_hidden_string[i + 1];
  282.   }
  283.   m_hidden_string[i] = (char)nChar;
  284.   if(!strnicmp(&m_hidden_string[HIDDEN_STRING_LEN - 6], "noodle", 6)) {
  285.     MessageBox("Why don't you eat a cup noodle?", "Advertisement");
  286.   }
  287.   if(!strnicmp(&m_hidden_string[HIDDEN_STRING_LEN - 4], "kban", 4)) {
  288.     MessageBox("Yes. I'm here.", "Identification");
  289.   }
  290.   if(!strnicmp(&m_hidden_string[HIDDEN_STRING_LEN - 4], "koji", 4)) {
  291.     MessageBox("Thank you for writing ECO_PCB.", "Acknowledgement");
  292.   }
  293.  
  294.   PREPARE();
  295.   switch(nChar) {
  296.     case VK_UP    : OnScrollCore(SCROLL_UP   );  break;
  297.     case VK_DOWN  : OnScrollCore(SCROLL_DOWN );  break;
  298.     case VK_LEFT  : OnScrollCore(SCROLL_LEFT );  break;
  299.     case VK_RIGHT : OnScrollCore(SCROLL_RIGHT);  break;
  300.     case ' ' : Invalidate();                     break;
  301.     case '+' : OnZoomCore(ID_VIEW_ZOOMIN );      break;
  302.     case '-' : OnZoomCore(ID_VIEW_ZOOMOUT);      break;
  303.     case 'f' : OnChangeFill();                   break;
  304.     case 'h' : OnChangeHole();                   break;
  305.     case '0' : OnChangeGrid(ID_SETUP_GRID_25_A); break;
  306.     case '1' : OnChangeGrid(ID_SETUP_GRID_25_1); break;
  307.     case '2' : OnChangeGrid(ID_SETUP_GRID_25_2); break;
  308.     case '4' : OnChangeGrid(ID_SETUP_GRID_25_4); break;
  309.     case '5' : OnChangeGrid(ID_SETUP_GRID_25_5); break;
  310.     default  : m_current_mmi->key_in(info, draw, nChar, nFlags); break;
  311.   }
  312. }
  313.  
  314. void CKBANView::ChangeCommandCore(KBAN_INFO& info, KBAN_DRAW& draw, KBAN_FUNCTION* func)
  315. {
  316.   m_current_mmi->end(info, draw);
  317.   m_current_mmi = func;
  318.   if(m_current_mmi->init(info, draw) == MENU_END) {
  319.     m_current_mmi = &m_default_func;
  320.     m_current_mmi->init(info, draw);
  321.   }
  322.   m_current_mmi->mouse_move(info, draw, m_pc_old, 0);
  323. }
  324.  
  325. void CKBANView::OnMouseGeneral(UINT nFlags, CPoint point, MOUSE_FUNC func)
  326. {
  327.   PREPARE();
  328.   m_moved = TRUE;
  329.   m_dc_old.set(point.x, point.y);
  330.   dc.DPtoLP(&point);
  331.   m_pc_old.set(point.x, point.y);
  332.   XY pc(point.x, point.y);
  333.  
  334.   info.new_state().set(false);
  335.   if((m_current_mmi->*func)(info, draw, pc, nFlags) == FALSE) {
  336.     ChangeCommandCore(info, draw, &m_default_func);
  337.   }
  338.   if(info.new_state().get()) {
  339.     GetDocument()->SetNewState(info.new_state_str().c_str());
  340.   }
  341. }
  342.  
  343. void CKBANView::OnMouseMove(UINT nFlags, CPoint point)
  344. {
  345.   OnMouseGeneral(nFlags, point, KBAN_FUNCTION::mouse_move);
  346. }
  347.  
  348. void CKBANView::OnLButtonUp(UINT nFlags, CPoint point)
  349. {
  350.   OnMouseGeneral(nFlags, point, KBAN_FUNCTION::mouse_left_up);
  351. }
  352.  
  353. void CKBANView::OnLButtonDown(UINT nFlags, CPoint point)
  354. {
  355.   OnMouseGeneral(nFlags, point, KBAN_FUNCTION::mouse_left_down);
  356. }
  357.  
  358. void CKBANView::OnRButtonUp(UINT nFlags, CPoint point)
  359. {
  360.   KBAN_INFO& info = GetDocument()->kban_info();
  361.   if((m_current_mmi != &m_default_func) || info.bCaptured()) {
  362.     OnMouseGeneral(nFlags, point, KBAN_FUNCTION::mouse_right_up);
  363.   } else {
  364.     CClientDC dc(this);
  365.     OnPrepareDC(&dc);
  366.     CPoint lp = point;
  367.     dc.DPtoLP(&lp);
  368.     XY pc(lp.x, lp.y);
  369.     XY ac;
  370.     GRID& grid = info.grid();
  371.     grid.xy_pc2ac(pc, ac);
  372.  
  373.     // what's under the mouse cursor?
  374.     PRIMITIVE& prim = info.kban_data().primitive();
  375.     PIN_LIST& pin_list = prim.layer(info.active_layer().get_pin_layer()).pin_list();
  376.     m_ctxt_target_pin = pin_list.search(ac);
  377.     LINE_LIST& line_list = prim.layer(info.active_layer().get()).line_list();
  378.     m_ctxt_target_line = line_list.search(10, ac);
  379.     COMPONENT_LIST& comp_list = info.kban_data().component_list();
  380.     m_ctxt_target_comp = comp_list.search(ac);
  381.  
  382.     // construct a context menu
  383.     CMenu menu;
  384.     menu.LoadMenu(IDR_CONTEXTMENU);
  385.     CMenu* pContextMenu = menu.GetSubMenu(0);
  386.     if(m_ctxt_target_pin != NULL) {
  387.       pContextMenu->AppendMenu(MF_STRING, ID_CTXT_EDIT_PIN, "Edit Pin");
  388.     }
  389.     if(m_ctxt_target_pin != NULL) {
  390.       pContextMenu->AppendMenu(MF_SEPARATOR);
  391.     }
  392.     if(m_ctxt_target_pin != NULL) {
  393.       if(m_ctxt_target_pin->is_selected()) {
  394.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_UNSELECT_PIN, "Unselect Pin");
  395.       } else {
  396.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_SELECT_PIN, "Select Pin");
  397.       }
  398.     }
  399.     if(m_ctxt_target_line != NULL) {
  400.       if(m_ctxt_target_line->is_selected()) {
  401.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_UNSELECT_LINE, "Unselect Line");
  402.       } else {
  403.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_SELECT_LINE, "Select Line");
  404.       }
  405.     }
  406.     if(m_ctxt_target_comp != NULL) {
  407.       if(m_ctxt_target_comp->is_selected()) {
  408.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_UNSELECT_COMPONENT, "Unselect Component");
  409.       } else {
  410.         pContextMenu->AppendMenu(MF_STRING, ID_CTXT_SELECT_COMPONENT, "Select Component");
  411.       }
  412.     }
  413.  
  414.     pContextMenu->RemoveMenu(ID_APP_ABOUT, MF_BYCOMMAND);
  415.     ClientToScreen(&point);
  416.     pContextMenu->TrackPopupMenu(
  417.       TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
  418.       point.x, point.y, this
  419.     );
  420.     menu.Detach();
  421.   }
  422. }
  423.  
  424. void CKBANView::OnRButtonDown(UINT nFlags, CPoint point)
  425. {
  426.   OnMouseGeneral(nFlags, point, KBAN_FUNCTION::mouse_right_down);
  427. }
  428.  
  429. void CKBANView::OnContextEditPin()
  430. {
  431.   PREPARE();
  432.  
  433.   PIN_ELEMENT& target = *m_ctxt_target_pin;
  434.  
  435.   draw.draw_primitive_pin_target(target);
  436.  
  437.   CEditPinDialog dialog(info.apt_pin_table(), target, AfxGetMainWnd());
  438.   draw.draw_primitive_pin_target(target);
  439.   int result = dialog.DoModal();
  440.   draw.erase_primitive_pin(target);
  441.   if(result == IDOK) {
  442.     target = dialog.GetPinElement();
  443.     info.apt_pin_table() = dialog.GetAptTable();
  444.     info.SetModifiedFlag();
  445.   }
  446.   uint layer = info.active_layer().get_pin_layer();
  447.   draw.draw_primitive_pin(target, layer);
  448.   GetDocument()->SetNewState("Edit Pin");
  449. }
  450.  
  451. #define UPDATE_bSelected() \
  452.   { \
  453.     KBAN_DATA& kban_data = info.kban_data(); \
  454.     KBAN_DATA kban_data_selected; \
  455.     kban_data.collect_selected_items(kban_data_selected); \
  456.     if(kban_data_selected.empty()) { \
  457.       info.bSelected() = false; \
  458.     } else { \
  459.       info.bSelected() = true; \
  460.     } \
  461.   }
  462.  
  463. void CKBANView::OnContextSelectPin()
  464. {
  465.   PREPARE();
  466.   PIN_ELEMENT& target = *m_ctxt_target_pin;
  467.   target.select();
  468.   draw.draw_primitive_pin_target(target);
  469.   info.bSelected() = true;
  470.   GetDocument()->SetNewState("Select Pin");
  471. }
  472.  
  473. void CKBANView::OnContextUnselectPin()
  474. {
  475.   PREPARE();
  476.   PIN_ELEMENT& target = *m_ctxt_target_pin;
  477.   target.unselect();
  478.   draw.draw_primitive_pin(target, info.active_layer().get_pin_layer());
  479.   UPDATE_bSelected();
  480.   GetDocument()->SetNewState("Unselect Pin");
  481. }
  482.  
  483. void CKBANView::OnContextSelectLine()
  484. {
  485.   PREPARE();
  486.   LINE_ELEMENT& target = *m_ctxt_target_line;
  487.   target.select();
  488.   draw.draw_primitive_line_target(target);
  489.   info.bSelected() = true;
  490.   GetDocument()->SetNewState("Select Line");
  491. }
  492.  
  493. void CKBANView::OnContextUnselectLine()
  494. {
  495.   PREPARE();
  496.   LINE_ELEMENT& target = *m_ctxt_target_line;
  497.   target.unselect();
  498.   draw.draw_primitive_line(target, info.active_layer().get());
  499.   UPDATE_bSelected();
  500.   GetDocument()->SetNewState("Unselect Line");
  501. }
  502.  
  503. void CKBANView::OnContextSelectComponent()
  504. {
  505.   PREPARE();
  506.   COMPONENT_ELEMENT& target = *m_ctxt_target_comp;
  507.   target.select();
  508.   draw.draw_one_component_target(target, info.active_layer().get());
  509.   info.bSelected() = true;
  510.   GetDocument()->SetNewState("Select Component");
  511. }
  512.  
  513. void CKBANView::OnContextUnselectComponent()
  514. {
  515.   PREPARE();
  516.   COMPONENT_ELEMENT& target = *m_ctxt_target_comp;
  517.   target.unselect();
  518.   draw.draw_one_component(target, info.active_layer().get());
  519.   UPDATE_bSelected();
  520.   GetDocument()->SetNewState("Unselect Component");
  521. }
  522.  
  523. void CKBANView::OnSize(UINT nType, int cx, int cy)
  524. {
  525.   XY pc_win_size(cx, cy);
  526.   KBAN_INFO& info = GetDocument()->kban_info();
  527.   GRID& grid = info.grid();
  528.   grid.set_pc_win_size(pc_win_size);
  529.   CScrollView::OnSize(nType, cx, cy);
  530.   SetScrollSizes(
  531.     MM_TEXT,
  532.     CSize(grid.get_pc_design_size().x(), grid.get_pc_design_size().y()),
  533.     CSize(pc_win_size.x() / 2, pc_win_size.y() / 2)
  534.   );
  535. }
  536.  
  537. void CKBANView::OnMove(int x, int y)
  538. {
  539.   Invalidate();
  540. }
  541.  
  542. void CKBANView::OnVScroll(UINT nCode, UINT nPos, CScrollBar* pScrollBar)
  543. {
  544.   // m_bDisableRedraw = true;
  545.  
  546.   // To reduce the number of redrawing, Invalidate() must be before
  547.   // calling CScrollView::OnVScroll()
  548.   PREPARE();
  549.   if(m_current_mmi->pre_redraw(info, draw) == FALSE) {
  550.     ChangeCommandCore(info, draw, &m_default_func);
  551.   }
  552.   Invalidate();
  553.   CScrollView::OnVScroll(nCode, nPos, pScrollBar);
  554.  
  555.   m_bDisableRedraw = false;
  556. }
  557.  
  558. void CKBANView::OnHScroll(UINT nCode, UINT nPos, CScrollBar* pScrollBar)
  559. {
  560.   // m_bDisableRedraw = true;
  561.  
  562.   // To reduce the number of redrawing, Invalidate() must be before
  563.   // calling CScrollView::OnHScroll()
  564.   PREPARE();
  565.   if(m_current_mmi->pre_redraw(info, draw) == FALSE) {
  566.     ChangeCommandCore(info, draw, &m_default_func);
  567.   }
  568.   Invalidate();
  569.   CScrollView::OnHScroll(nCode, nPos, pScrollBar);
  570.  
  571.   m_bDisableRedraw = false;
  572. }
  573.  
  574. void CKBANView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
  575. {
  576.   if(!bActivate) {
  577.     Invalidate();
  578.   }
  579. }
  580.  
  581. void CKBANView::OnUndo()
  582. {
  583.   if(GetDocument()->Undo()) {
  584.     Invalidate();
  585.   }
  586. }
  587.  
  588. void CKBANView::OnUpdateUndo(CCmdUI* pCmdUI)
  589. {
  590.   if(GetDocument()->IsUndoable()) {
  591.     pCmdUI->Enable(true);
  592.     char str[100];
  593.     sprintf(str, "Undo %s\tCtrl+Z", GetDocument()->GetUndoName());
  594.     pCmdUI->SetText(str);
  595.   } else {
  596.     pCmdUI->Enable(false);
  597.     pCmdUI->SetText("Undo\tCtrl+Z");
  598.   }
  599. }
  600.  
  601. void CKBANView::OnRedo()
  602. {
  603.   if(GetDocument()->Redo()) {
  604.     Invalidate();
  605.   }
  606. }
  607.  
  608. void CKBANView::OnUpdateRedo(CCmdUI* pCmdUI)
  609. {
  610.   if(GetDocument()->IsRedoable()) {
  611.     pCmdUI->Enable(true);
  612.     char str[100];
  613.     sprintf(str, "Redo %s", GetDocument()->GetRedoName());
  614.     pCmdUI->SetText(str);
  615.   } else {
  616.     pCmdUI->Enable(false);
  617.     pCmdUI->SetText("Redo");
  618.   }
  619. }
  620.  
  621. void CKBANView::OnUpdatePaste(CCmdUI* pCmdUI)
  622. {
  623.   KBAN_INFO& info = GetDocument()->kban_info();
  624.   pCmdUI->Enable(info.bClipped());
  625. }
  626.  
  627. void CKBANView::OnUpdateUnselectAll(CCmdUI* pCmdUI)
  628. {
  629.   KBAN_INFO& info = GetDocument()->kban_info();
  630.   pCmdUI->Enable(info.bSelected());
  631. }
  632.  
  633. void CKBANView::OnZoomCore(UINT nID)
  634. {
  635.   CPoint point = GetScrollPosition();
  636.   XY pc_win_base(point.x, point.y);
  637.   KBAN_INFO& info = GetDocument()->kban_info();
  638.   GRID& grid = info.grid();
  639.   switch(nID) {
  640.     case ID_VIEW_ZOOMIN  : grid.zoom_in (pc_win_base); break;
  641.     case ID_VIEW_ZOOMOUT : grid.zoom_out(pc_win_base); break;
  642.     case ID_VIEW_ALL : {
  643.       XY ac_min = info.kban_data().get_min();
  644.       XY ac_max = info.kban_data().get_max();
  645.       grid.zoom_window(ac_min, ac_max, pc_win_base);
  646.       break;
  647.     }
  648.   }
  649.   const XY& pc_design_size = grid.get_pc_design_size();
  650.   SetScrollSizes(
  651.     MM_TEXT,
  652.     CSize(pc_design_size.x(), pc_design_size.y()),
  653.     CSize(grid.get_pc_win_size().x() / 2, grid.get_pc_win_size().y() / 2)
  654.     );
  655.   ScrollToPosition(CPoint(pc_win_base.x(), pc_win_base.y()));
  656.   Invalidate();
  657. }
  658.  
  659. void CKBANView::OnRedraw()
  660. {
  661.   Invalidate();
  662. }
  663.  
  664. void CKBANView::OnChangeSnap()
  665. {
  666.   KBAN_INFO& info = GetDocument()->kban_info();
  667.   info.grid().snap_change();
  668. }
  669.  
  670. void CKBANView::OnUpdateSnap(CCmdUI* pCmdUI)
  671. {
  672.   KBAN_INFO& info = GetDocument()->kban_info();
  673.   pCmdUI->SetCheck(info.grid().snap_get());
  674. }
  675.  
  676. void CKBANView::OnChangePinOnCommon()
  677. {
  678.   KBAN_INFO& info = GetDocument()->kban_info();
  679.   info.active_layer().pin_on_common().change();
  680. }
  681.  
  682. void CKBANView::OnUpdatePinOnCommon(CCmdUI* pCmdUI)
  683. {
  684.   KBAN_INFO& info = GetDocument()->kban_info();
  685.   pCmdUI->SetCheck(info.active_layer().pin_on_common().get());
  686. }
  687.  
  688. void CKBANView::OnChangeFill()
  689. {
  690.   KBAN_INFO& info = GetDocument()->kban_info();
  691.   info.fill().change();
  692.   Invalidate();
  693. }
  694.  
  695. void CKBANView::OnUpdateFill(CCmdUI* pCmdUI)
  696. {
  697.   KBAN_INFO& info = GetDocument()->kban_info();
  698.   pCmdUI->SetCheck(info.fill().get());
  699. }
  700.  
  701. void CKBANView::OnChangeHole()
  702. {
  703.   KBAN_INFO& info = GetDocument()->kban_info();
  704.   info.hole().change();
  705.   Invalidate();
  706. }
  707.  
  708. void CKBANView::OnUpdateHole(CCmdUI* pCmdUI)
  709. {
  710.   KBAN_INFO& info = GetDocument()->kban_info();
  711.   pCmdUI->SetCheck(info.hole().get());
  712. }
  713.  
  714. void CKBANView::OnHelpDebug()
  715. {
  716.   CClientDC dc(this);
  717.   OnPrepareDC(&dc);
  718.   int t1 = ::GetCurrentTime();
  719.   for(int i = 0; i < 50; i++) {
  720.     OnEraseBkgnd(&dc);
  721.     OnDraw(&dc);
  722.   }
  723.   int t2 = ::GetCurrentTime();
  724.   int td = t2 - t1;
  725.   char str[300];
  726.   sprintf(str, "Elapsed Time : %d.%03d", td / 1000, td % 1000);
  727.   MessageBox(str, "Elapsed Time");
  728. }
  729.  
  730. void CKBANView::OnChangeGrid(UINT nID)
  731. {
  732.   m_nGridID = nID;
  733.   KBAN_INFO& info = GetDocument()->kban_info();
  734.   GRID& grid = info.grid();
  735.   switch(nID) {
  736.     case ID_SETUP_GRID_10_1 : grid.set_grid_width(1000,  1); break;
  737.     case ID_SETUP_GRID_10_2 : grid.set_grid_width(1000,  2); break;
  738.     case ID_SETUP_GRID_10_5 : grid.set_grid_width(1000,  5); break;
  739.     case ID_SETUP_GRID_10_A : grid.set_grid_width(1000, 10); break;
  740.     case ID_SETUP_GRID_17_1 : grid.set_grid_width(1778,  1); break;
  741.     case ID_SETUP_GRID_17_2 : grid.set_grid_width(1778,  2); break;
  742.     case ID_SETUP_GRID_25_1 : grid.set_grid_width(2540,  1); break;
  743.     case ID_SETUP_GRID_25_2 : grid.set_grid_width(2540,  2); break;
  744.     case ID_SETUP_GRID_25_4 : grid.set_grid_width(2540,  4); break;
  745.     case ID_SETUP_GRID_25_5 : grid.set_grid_width(2540,  5); break;
  746.     case ID_SETUP_GRID_25_A : grid.set_grid_width(2540, 10); break;
  747.   }
  748.   Invalidate();
  749. }
  750.  
  751. void CKBANView::OnSetGridWidth()
  752. {
  753.   KBAN_INFO& info = GetDocument()->kban_info();
  754.   GRID& grid = info.grid();
  755.   int main = grid.get_main_grid_width();
  756.   int sub  = grid.get_sub_grid_width();
  757.   int div  = main / sub;
  758.   CSetGridDialog dlg(this, main, div);
  759.   if(dlg.DoModal() == IDOK) {
  760.     grid.set_grid_width(dlg.main_grid_width(), dlg.div());
  761.     Invalidate();
  762.   }
  763. }
  764.  
  765. void CKBANView::OnUpdateGrid(CCmdUI* pCmdUI)
  766. {
  767.   pCmdUI->SetCheck(pCmdUI->m_nID == m_nGridID);
  768. }
  769.  
  770. void CKBANView::OnResetGrid()
  771. {
  772.   KBAN_INFO& info = GetDocument()->kban_info();
  773.   GRID& grid = info.grid();
  774.   grid.set_grid_origin(XY(0, 0));
  775.   Invalidate();
  776. }
  777.  
  778. void CKBANView::OnAptPin()
  779. {
  780.   KBAN_INFO& info = GetDocument()->kban_info();
  781.   APT_TABLE& table = info.apt_pin_table();
  782.   APT_TABLE pin_table_purged;
  783.   APT_TABLE line_table_purged;
  784.   info.kban_data().collect_aperture(pin_table_purged, line_table_purged);
  785.   CAptChgPinDialog dlg(this, table, pin_table_purged, info.apt_pin());
  786.   if(dlg.DoModal() == IDOK) {
  787.     table = dlg.apt_table();
  788.     info.apt_pin() = dlg.aperture();
  789.   }
  790. }
  791.  
  792. void CKBANView::OnAptLine()
  793. {
  794.   KBAN_INFO& info = GetDocument()->kban_info();
  795.   APT_TABLE& table = info.apt_line_table();
  796.   APT_TABLE pin_table_purged;
  797.   APT_TABLE line_table_purged;
  798.   info.kban_data().collect_aperture(pin_table_purged, line_table_purged);
  799.   CAptChgLineDialog dlg(this, table, line_table_purged, info.apt_line());
  800.   if(dlg.DoModal() == IDOK) {
  801.     table = dlg.apt_table();
  802.     info.apt_line() = dlg.aperture();
  803.   }
  804. }
  805.  
  806. void CKBANView::OnChangeLayer(UINT nID)
  807. {
  808.   m_nLayerID = nID;
  809.   KBAN_INFO& info = GetDocument()->kban_info();
  810.   ACTIVE_LAYER& layer = info.active_layer();
  811.   switch(nID) {
  812.     case ID_LAYER_PCOMMON : layer.set(LAYER_PATTERN_COMMON); break;
  813.     case ID_LAYER_PTOP    : layer.set(LAYER_PATTERN_TOP   ); break;
  814.     case ID_LAYER_PBOTTOM : layer.set(LAYER_PATTERN_BOTTOM); break;
  815.     case ID_LAYER_STOP    : layer.set(LAYER_SILK_TOP      ); break;
  816.     case ID_LAYER_SBOTTOM : layer.set(LAYER_SILK_BOTTOM   ); break;
  817.   }
  818.   Invalidate();
  819. }
  820.  
  821. void CKBANView::OnUpdateLayer(CCmdUI* pCmdUI)
  822. {
  823.   pCmdUI->SetCheck(pCmdUI->m_nID == m_nLayerID);
  824. }
  825.  
  826. void CKBANView::OnChangeShowLayer(UINT nID)
  827. {
  828.   KBAN_INFO& info = GetDocument()->kban_info();
  829.   FLAG* lflags = info.lflags();
  830.   switch(nID) {
  831.     case ID_LAYER_SHOW_PCOMMON : lflags[LAYER_PATTERN_COMMON].change(); break;
  832.     case ID_LAYER_SHOW_PTOP    : lflags[LAYER_PATTERN_TOP   ].change(); break;
  833.     case ID_LAYER_SHOW_PBOTTOM : lflags[LAYER_PATTERN_BOTTOM].change(); break;
  834.     case ID_LAYER_SHOW_STOP    : lflags[LAYER_SILK_TOP      ].change(); break;
  835.     case ID_LAYER_SHOW_SBOTTOM : lflags[LAYER_SILK_BOTTOM   ].change(); break;
  836.   }
  837.   Invalidate();
  838. }
  839.  
  840. void CKBANView::OnUpdateShowLayer(CCmdUI* pCmdUI)
  841. {
  842.   KBAN_INFO& info = GetDocument()->kban_info();
  843.   FLAG* lflags = info.lflags();
  844.   switch(pCmdUI->m_nID) {
  845.     case ID_LAYER_SHOW_PCOMMON : pCmdUI->SetCheck(lflags[LAYER_PATTERN_COMMON].get()); break;
  846.     case ID_LAYER_SHOW_PTOP    : pCmdUI->SetCheck(lflags[LAYER_PATTERN_TOP   ].get()); break;
  847.     case ID_LAYER_SHOW_PBOTTOM : pCmdUI->SetCheck(lflags[LAYER_PATTERN_BOTTOM].get()); break;
  848.     case ID_LAYER_SHOW_STOP    : pCmdUI->SetCheck(lflags[LAYER_SILK_TOP      ].get()); break;
  849.     case ID_LAYER_SHOW_SBOTTOM : pCmdUI->SetCheck(lflags[LAYER_SILK_BOTTOM   ].get()); break;
  850.   }
  851. }
  852.  
  853. void CKBANView::OnEditCutCopyDelete(UINT nID)
  854. {
  855.   PREPARE();
  856.   if(info.bSelected()) {
  857.     info.bSelected() = false;
  858.     KBAN_DATA& kban_data = info.kban_data();
  859.     KBAN_DATA kban_data_selected;
  860.     kban_data.collect_selected_items(kban_data_selected);
  861.     uint active_layer = info.active_layer().get();
  862.     if(nID == ID_EDIT_COPY) {
  863.       kban_data.unselect();
  864.       draw.draw_kban_data(kban_data_selected, active_layer);
  865.     } else {
  866.       info.SetModifiedFlag();
  867.       kban_data.remove_selected_items();
  868.       draw.erase_kban_data(kban_data_selected, active_layer);
  869.     }
  870.     if(nID != ID_EDIT_DELETE) {
  871.       XY ac_base = kban_data_selected.get_min();
  872.       info.grid().snap_min(ac_base);
  873.       KBAN_DATA& kban_data_clipped = info.clipped_data();
  874.       kban_data_clipped.clear();
  875.       kban_data_selected.shift(- ac_base, kban_data_clipped);
  876.       kban_data_clipped.unselect();
  877.       info.bClipped() = true;
  878.     }
  879.  
  880.     // register undo info
  881.     switch(nID) {
  882.       case ID_EDIT_CUT    : GetDocument()->SetNewState("Cut");    break;
  883.       case ID_EDIT_COPY   : GetDocument()->SetNewState("Copy");   break;
  884.       case ID_EDIT_DELETE : GetDocument()->SetNewState("Delete"); break;
  885.     }
  886.   }
  887. }
  888.  
  889. void CKBANView::OnUpdateCutCopyDelete(CCmdUI* pCmdUI)
  890. {
  891.   KBAN_INFO& info = GetDocument()->kban_info();
  892.   pCmdUI->Enable(info.bSelected());
  893. }
  894.  
  895. void CKBANView::OnEditUnselectAll()
  896. {
  897.   PREPARE();
  898.   if(info.bSelected()) {
  899.     info.bSelected() = false;
  900.     KBAN_DATA& kban_data = info.kban_data();
  901.     KBAN_DATA kban_data_selected;
  902.     kban_data.collect_selected_items(kban_data_selected);
  903.     uint active_layer = info.active_layer().get();
  904.     draw.draw_kban_data(kban_data_selected, active_layer);
  905.     kban_data.unselect();
  906.     GetDocument()->SetNewState("Unselect All");
  907.   }
  908. }
  909.  
  910. void CKBANView::ChangeCommand(KBAN_FUNCTION* func)
  911. {
  912.   PREPARE();
  913.   ChangeCommandCore(info, draw, func);
  914. }
  915.  
  916. void CKBANView::OnChangeCommand(UINT nID)
  917. {
  918.   switch(nID) {
  919.     case ID_EDIT_BLOCK        : ChangeCommand(&m_edit_block       ); break;
  920.     case ID_EDIT_BLOCK_LAYER  : ChangeCommand(&m_edit_block_layer ); break;
  921.     case ID_EDIT_PASTE        : ChangeCommand(&m_edit_paste       ); break;
  922.     case ID_EDIT_PIN          : ChangeCommand(&m_edit_pin         ); break;
  923.     case ID_EDIT_PULL         : ChangeCommand(&m_edit_pull        ); break;
  924.     case ID_EDIT_DIVIDE       : ChangeCommand(&m_edit_divide      ); break;
  925.     case ID_EDIT_MOVE_LINE    : ChangeCommand(&m_edit_move_line   ); break;
  926.     case ID_SETUP_GRID_ORIGIN : ChangeCommand(&m_setup_grid_origin); break;
  927.     case ID_PLACE_PIN         : ChangeCommand(&m_place_pin        ); break;
  928.     case ID_PLACE_LINE        : ChangeCommand(&m_place_line       ); break;
  929.     case ID_PLACE_COMPONENT   : ChangeCommand(&m_place_component  ); break;
  930.     case ID_DELETE_PIN        : ChangeCommand(&m_delete_pin       ); break;
  931.     case ID_DELETE_LINE       : ChangeCommand(&m_delete_line      ); break;
  932.     case ID_DELETE_COMPONENT  : ChangeCommand(&m_delete_component ); break;
  933.   }
  934. }
  935.  
  936. void CKBANView::OnIsEmpty()
  937. {
  938.   KBAN_INFO& info = GetDocument()->kban_info();
  939.   if(info.kban_data().empty()) {
  940.     MessageBox("Empty", "Help - Is Empty");
  941.   } else {
  942.     MessageBox("Not Empty", "Help - Is Empty");
  943.   }
  944. }
  945.  
  946. void CKBANView::OnUserMessage(UINT wParam, LONG lParam)
  947. {
  948.   PREPARE();
  949.   if(m_current_mmi->user_message(info, draw, wParam, lParam) == FALSE) {
  950.     ChangeCommandCore(info, draw, &m_default_func);
  951.   }
  952. }
  953.  
  954. void CKBANView::OnToolsPurge()
  955. {
  956.   KBAN_INFO& info = GetDocument()->kban_info();
  957.   PRIMITIVE& primitive = info.kban_data().primitive();
  958.   int count = 0;
  959.   for(int i = 0; i < LAYER_NUMBER; i++) {
  960.     LINE_LIST& line_list = primitive.layer(i).line_list();
  961.     count += line_list.purge_lines();
  962.   }
  963.   char str[300];
  964.   sprintf(str, "The number of lines eliminated: %d", count);
  965.   MessageBox(str, "Function Purge");
  966.   info.SetModifiedFlag();
  967.   info.new_state().set(true);
  968.   info.new_state_str() = "Tools Purge";
  969.   GetDocument()->SetNewState(info.new_state_str().c_str());
  970.   Invalidate();
  971. }
  972.